// 10_generics.rs
// Rust 泛型教程

fn main() {
    // 1. 去除重复代码
    let number_list = vec![34, 50, 25, 100, 65];
    let largest = largest_number(&number_list);
    println!("最大的数字是: {}", largest);
    
    let char_list = vec!['y', 'm', 'a', 'q'];
    let largest = largest_char(&char_list);
    println!("最大的字符是: {}", largest);
    
    // 2. 使用泛型函数
    let number_list = vec![34, 50, 25, 100, 65];
    let largest = largest_generic(&number_list);
    println!("最大的数字是: {}", largest);
    
    let char_list = vec!['y', 'm', 'a', 'q'];
    let largest = largest_generic(&char_list);
    println!("最大的字符是: {}", largest);
    
    // 3. 结构体中的泛型
    let integer = Point { x: 5, y: 10 };
    let float = Point { x: 1.0, y: 4.0 };
    let both = Point { x: 5, y: 4.0 };  // x 和 y 可以是不同类型
    
    println!("整数点: ({}, {})", integer.x, integer.y);
    println!("浮点数点: ({}, {})", float.x, float.y);
    println!("混合点: ({}, {})", both.x, both.y);
    
    // 4. 为结构体实现方法
    let p = Point { x: 5, y: 10 };
    println!("p.x = {}", p.x());
    
    let p1 = Point { x: 5, y: 10.4 };
    let p2 = Point { x: "Hello", y: 'c' };
    let p3 = p1.mixup(p2);
    println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
    
    // 5. 枚举中的泛型
    let integer = Some(5);
    let float = Some(5.0);
    
    println!("整数 Option: {:?}", integer);
    println!("浮点数 Option: {:?}", float);
    
    // 6. 方法定义中的泛型
    let list = vec![1, 2, 3];
    let list2 = vec!['a', 'b', 'c'];
    
    println!("整数列表: {:?}", list);
    println!("字符列表: {:?}", list2);
}

// 1. 为不同类型编写相似的函数
fn largest_number(list: &[i32]) -> i32 {
    let mut largest = list[0];
    
    for &item in list {
        if item > largest {
            largest = item;
        }
    }
    
    largest
}

fn largest_char(list: &[char]) -> char {
    let mut largest = list[0];
    
    for &item in list {
        if item > largest {
            largest = item;
        }
    }
    
    largest
}

// 2. 使用泛型函数避免重复
fn largest_generic<T: PartialOrd + Copy>(list: &[T]) -> T {
    let mut largest = list[0];
    
    for &item in list {
        if item > largest {
            largest = item;
        }
    }
    
    largest
}

// 3. 结构体中的泛型
struct Point<T, U> {
    x: T,
    y: U,
}

// 4. 为使用泛型的结构体实现方法
impl<T, U> Point<T, U> {
    fn x(&self) -> &T {
        &self.x
    }
}

// 为特定类型的泛型结构体实现方法
impl Point<f32, f32> {
    fn distance_from_origin(&self) -> f32 {
        (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
}

// 混合两个 Point 的值
impl<T, U> Point<T, U> {
    fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
        Point {
            x: self.x,
            y: other.y,
        }
    }
}

// 5. 枚举中的泛型
enum Option<T> {
    Some(T),
    None,
}

enum Result<T, E> {
    Ok(T),
    Err(E),
}

// 6. 方法定义中的泛型
#[derive(Debug)]
struct Point2<T> {
    x: T,
    y: T,
}

impl<T> Point2<T> {
    fn new(x: T, y: T) -> Self {
        Point2 { x, y }
    }
}

// 为实现了特定 trait 的泛型实现方法
impl<T: std::ops::Add<Output = T> + Copy> Point2<T> {
    fn sum(&self) -> T {
        self.x + self.y
    }
}